"""
#!/usr/bin/python3
# coding:utf-8
#
# Copyright (C) 2024 - 2024 Jasonakeke， Inc. All Rights Reserved
# @Desc	   ：我们自己开发的 web 服务器
# @Time    : 2024/7/31 22:17
# @Author  : Code_By_Jasonakeke
# @Email   : 2284037977@qq.com
# @File    : my_web.py
# @IDE     : PyCharm
"""
from socket import socket, AF_INET, SOCK_STREAM
from threading import Thread
from time import strftime, localtime

from _socket import SOL_SOCKET, SO_REUSEADDR

from MyFramework import handle_request


# 开发自己的 web 服务器主类
class MyWebHttpServer(object):
	def __init__(self, port):
		# 创建 HTTP 服务器的套接字
		server_socket = socket(AF_INET, SOCK_STREAM)
		# 设置端口号复用，出现退出之后，不需要等待几分钟，直接释放端口
		server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
		server_socket.bind(('', port))
		server_socket.listen(128)
		self.server_socket = server_socket

	# 处理请求的函数
	@staticmethod
	def hande_browser_request(new_socket):
		# 接收客户端的请求
		recv_data = new_socket.recv(4096)
		# 如果没有收到数据，那么请求无效，关闭套接字，直接退出
		if len(recv_data) == 0:
			new_socket.close()
			return
		# 对接收的字节数据，转换成字符
		request_data = recv_data.decode('utf-8')
		print("浏览器请求的数据：", request_data)
		request_array = request_data.split(' ', maxsplit = 2)
		# 得到请求路径
		request_path = request_array[1]
		print("请求路径是：", request_path)
		# 如果请求路径是 /，自动设置为 /index.html
		if request_path == '/':
			request_path = '/index.html'
		# 根据请求路径来判断是否是动态资源函数静态资源
		if request_path.endswith('.html'):
			''' 动态资源的请求 '''
			# 动态资源的处理交给 Web 框架来处理，需要把请求参数传给 Web 框架，可能会有多个参数，所以采用字典结果
			params = {
				'request_path': request_path
			}
			# Web 框架处理动态资源请求之后，返回一个响应
			response = handle_request(params)
			new_socket.send(response)
			new_socket.close()

		else:
			''' 静态资源的请求 '''
			# 响应主体页面
			response_body = None
			# 响应头
			response_header = None
			# 响应头第一行
			response_first_line = None
			# 其实就是根据请求路径读取 /static/ 目录中静态的文件数据，响应给客户端
			try:
				# 读取 static 目录中的文件数据，rb 模式是一种兼容模式，可以打开图片，也可以打开 js
				with open('static' + request_path, 'rb') as f:
					response_body = f.read()
				# if request_path.endswith('.jpg'):
				# 	response_type = 'image/wbep'
				response_first_line = 'HTTP/1.1 200 OK\r\n'
			except Exception as e:
				# 浏览器想读取的文件可能不存在
				with open('static/404.html', 'rb') as f:
					# 响应主体页面
					response_body = f.read()
				response_first_line = 'HTTP/1.1 404 Not Found\r\n'
			finally:
				# 响应头
				response_header = 'Server: keke\r\n'
				# 组成响应数据，发给客户端
				response = (response_first_line + response_header + '\r\n').encode('utf-8') + response_body
				new_socket.send(response)
				# 关闭套接字
				new_socket.close()

	# 启动服务器 ，并且接收客户端的请求
	def start(self):
		# 循环并且多线程来接收客户端的请求
		while True:
			new_socket, ip_port = self.server_socket.accept()
			print("客户端的 ip 和端口是：", ip_port)
			# 一个客户端请求交给一个线程处理
			sub_thread = Thread(target = self.hande_browser_request, args = (new_socket,))
			# 设置守护线程
			sub_thread.daemon = True
			sub_thread.start()


def main():
	# 创建服务器对象
	web_server = MyWebHttpServer(8080)
	# 启动服务器
	web_server.start()


if __name__ == '__main__':
	main()
